home *** CD-ROM | disk | FTP | other *** search
-
- /* Generated by Interface Builder */
-
- #import "StereoView.h"
- #import "CubeView.h"
- #import "Help.h"
- #import <appkit/Control.h>
- #import <appkit/Button.h>
- #import <appkit/graphics.h>
- #import <appkit/OpenPanel.h>
- #import <NXCType.h>
- #import <stdlib.h>
- #import <math.h>
- #import <strings.h>
- #import <appkit/Pasteboard.h>
- #import <dpsclient/dpsNeXT.h>
- #import <defaults/defaults.h> // for NXArgv
- #import <libc.h> // for chdir, getwd
- #define EYE 2.9/57.3
- #define rad_to_deg (180./M_PI)
- #define MAXLINE 10000
- #define MAXNUM 10000
- #define MAXALLOC 100
- #define TRUE -1
- #define FALSE !TRUE
-
- @implementation StereoView
-
- - initFrame:(const NXRect *)frameRect
- {
-
- textDidChange = 0;
- textNeedsSaving = 0;
- toshow = (datapoints **) calloc(MAXALLOC, sizeof(datapoints *));
- max_path = 100;
- path = (float *) calloc(2*max_path, sizeof(float));
- eyeOffset = EYE;
- openReq = [OpenPanel new];
- saveReq = [SavePanel new];
- [super initFrame:frameRect];
- bcopy(frameRect,&left_Rect,sizeof(NXRect));
- bcopy(frameRect,&right_Rect,sizeof(NXRect));
-
- NXDivideRect(&left_Rect,&right_Rect,NX_WIDTH(frameRect)/2.,2);
-
- /*
- NXInsetRect(&left_Rect,0.1*NX_WIDTH(&left_Rect),0.1*NX_HEIGHT(&left_Rect));
- NXInsetRect(&right_Rect,0.1*NX_WIDTH(&right_Rect),0.1*NX_HEIGHT(&right_Rect));
- */
- leftView = [[CubeView alloc] initFrame:&left_Rect];
- rightView = [[CubeView alloc] initFrame:&right_Rect];
- [self setDrawOrigin:(NXCoord) NX_X(frameRect):(NXCoord) NX_Y(frameRect)];
- [self addSubview:leftView];
- [self addSubview:rightView];
- [self setAutoresizeSubviews:TRUE];
- fileNAME = (char *) calloc(1,256);
- strcpy(fileNAME,"Untitled");
- [self S_Reset:self];
- return self;
- }
-
- static char angle_buffer[20];
-
-
- - setDelegate:anObject
- {
- delegate = anObject;
- return self;
- }
-
- - copy:sender /* code contributed by Dan McCreary of NeXT */
- {
- id pb = [Pasteboard new]; /* global Pasteboard object */
- NXStream *st; /* stream to collect data in */
- char *data; /* actual data buffer */
- int length; /* length of data */
- int maxLength; /* (not used here) */
- /* To see how to use the pasteboard */
- /* see page 10-33 of the SysRefMan */
- [self prtCopy];
- /* declare that we will supply a */
- /* single type of data: PostScript */
- [pb declareTypes:&NXPostScriptPboard num:1 owner:self];
- /* get a stream which writes to memory */
- st = NXOpenMemory( NULL, 0, NX_WRITEONLY );
- /* write PostScript code for this view into the stream */
- [self copyPSCodeInside:NULL to:st];
- /* get actual data buffer from stream */
- NXGetMemoryBuffer( st, &data, &length, &maxLength );
- /* write PostScript data to pasteboard */
- [pb writeType:NXPostScriptPboard data:data length:length];
- /* deallocate stream, including its buffer */
- NXCloseMemory( st, NX_FREEBUFFER );
- [self display];
- return self;
- }
-
-
- -(BOOL)acceptsFirstResponder
- { /* make this view accept first */
- return YES; /* responder so it will understand copy */
- }
-
- /*
- -resignFirstResponder
- {
- return self;
- }
- */
- - showError:(char *)errorMessage
- {
- NXRunAlertPanel("Error", errorMessage, "OK", NULL, NULL);
- return self;
- }
-
- - prtCopy
- {
- [leftView printPSCode:leftView];
- [rightView printPSCode:rightView];
- [self display];
- return self;
- }
-
- - printPSCode:sender
- {
- [leftView printPSCode:leftView];
- [rightView printPSCode:rightView];
- [self display];
- [super printPSCode:self];
- [self display];
- return self;
- }
-
- - textChanged:sender
- {
- textDidChange = 1;
- return self;
- }
-
- - textEdited:sender
- {
- textNeedsSaving = 1;
- return self;
- }
-
- - plot:sender
- {
- NXStream *stream;
-
- if (textDidChange == 1) {
- if (delegate && [delegate respondsTo:@selector(stereoView:providePoints:)])
- [delegate stereoView:self providePoints:&stream];
- textDidChange = 0;
- [self readData:(NXStream *)stream];
- [leftView getStruct:&toshow:max_path:&path];
- [rightView getStruct:&toshow:max_path:&path];
- [leftView reScale:self];
- [rightView reScale:self];
- }
- [self set_Theta:self];
- [self set_Phi:self];
- [self set_dist:self];
- [self display];
- return self;
- }
-
- - clear:sender
- {
- long int count;
- datapoints **all_data = toshow, *thesedata;
-
- /* release existing data */
- while ((thesedata = *all_data) != (datapoints *) NULL) {
- free(thesedata->displayed);
- count = 0;
- while(thesedata->all[count] != (float *) NULL) {
- free(thesedata->all[count]);
- count++;
- }
- free(thesedata->all);
- free(thesedata);
- *all_data++ = (datapoints *) NULL;
- }
- [leftView getStruct:&toshow:max_path:&path];
- [rightView getStruct:&toshow:max_path:&path];
- [leftView clear:self];
- [rightView clear:self];
- [self set_Theta:self];
- [self set_Phi:self];
- [self set_dist:self];
- [self display];
- [self textChanged:self];
- return self;
- }
-
- - S_Reset:sender
- {
- float floatValue;
-
- [leftView getStruct:&toshow:max_path:&path];
- [rightView getStruct:&toshow:max_path:&path];
- [ThetaSlider setFloatValue:0.];
- floatValue = [ThetaSlider floatValue];
- sprintf(angle_buffer, "%6.2f", rad_to_deg*floatValue);
- [showTheta setStringValue:angle_buffer];
- [PhiSlider setFloatValue:0.];
- floatValue = [PhiSlider floatValue];
- sprintf(angle_buffer, "%6.2f", rad_to_deg*floatValue);
- [showPhi setStringValue:angle_buffer];
- [DistanceSlider setFloatValue:2.0];
- floatValue = [DistanceSlider floatValue];
- sprintf(angle_buffer, "%6.2f", floatValue);
- [showDist setStringValue:angle_buffer];
- [leftView Reset:leftView];
- [rightView Reset:rightView];
- [leftView setTheta:-eyeOffset];
- [rightView setTheta:+eyeOffset];
- [[self window] setTitle:fileNAME];
- [self display];
- return self;
- }
-
- - set_Theta:sender
- {
- float floatValue;
-
- floatValue = [ThetaSlider floatValue];
- sprintf(angle_buffer, "%6.2f", rad_to_deg*floatValue);
- [showTheta setStringValue:angle_buffer];
- [leftView setTheta:floatValue-eyeOffset];
- [rightView setTheta:floatValue+eyeOffset];
- [self display];
- return self;
- }
-
- - set_Phi:sender
- {
- float floatValue;
-
- floatValue = [PhiSlider floatValue];
-
- sprintf(angle_buffer, "%6.2f", rad_to_deg*floatValue);
- [showPhi setStringValue:angle_buffer];
- [leftView setPhi:floatValue];
- [rightView setPhi:floatValue];
- [self display];
- return self;
- }
-
-
- - set_dist:sender
- {
- float floatValue;
-
- floatValue = [DistanceSlider floatValue];
-
- sprintf(angle_buffer, "%6.2f", floatValue);
- [showDist setStringValue:angle_buffer];
- [leftView setdist:floatValue];
- [rightView setdist:floatValue];
- [self display];
- return self;
- }
-
- - setAxes:(int) intVal
- {
- [AxesButton setState:intVal];
- [leftView setAxes:intVal];
- [rightView setAxes:intVal];
- [self display];
- return self;
- }
-
- - (int)getAxes
- {
- return [AxesButton state];
- }
-
- - toggle_Axes:sender
- {
- [leftView toggleAxes:self];
- [rightView toggleAxes:self];
- [self display];
- return self;
- }
-
- - setCube:(int) intVal
- {
- [CubeButton setState:intVal];
- [leftView setCube:intVal];
- [rightView setCube:intVal];
- [self display];
- return self;
- }
-
- - (int)getCube
- {
- return [CubeButton state];
- }
-
- - toggle_Cube:sender
- {
- [leftView toggleCube:self];
- [rightView toggleCube:self];
- [self display];
- return self;
- }
-
- - setEyeOffset:(float) floatVal
- {
- int eye;
-
- eyeOffset = floatVal;
-
- if (floatVal < 0.)eye = NO;
- else eye = YES;
- [EyeButton setState:eye];
- [self set_Theta:self];
- [self display];
- return self;
- }
-
- - (float) getEyeOffset
- {
- return eyeOffset;
- }
-
- - toggle_Eyes:sender
- {
- [self setEyeOffset: - eyeOffset];
- return self;
- }
-
- - sizeTo:(NXCoord)width :(NXCoord)height
- {
- NXRect frameRect;
-
- [super sizeTo:width :height];
-
- /*
- [leftView free];
- [rightView free];
- */
- [self getFrame:&frameRect];
- bcopy(&frameRect,&left_Rect,sizeof(NXRect));
- bcopy(&frameRect,&right_Rect,sizeof(NXRect));
-
- NXDivideRect(&left_Rect,&right_Rect,NX_WIDTH(&frameRect)/2.,2);
-
- /*
- leftView = [[CubeView alloc] initFrame:&left_Rect];
- rightView = [[CubeView alloc] initFrame:&right_Rect];
- */
- [leftView setFrame:&left_Rect];
- [leftView initialize];
- [rightView setFrame:&right_Rect];
- [rightView initialize];
- [self setDrawOrigin:(NXCoord) NX_X(&frameRect):(NXCoord) NX_Y(&frameRect)];
- /*
- [self addSubview:leftView];
- [self addSubview:rightView];
- [self setAutoresizeSubviews:TRUE];
- */
- [self S_Reset:self];
- return self;
- }
-
- - windowDidResize:sender
- {
- /* This is not received since the controller handles it */
- printf("windowDidResize for StereoView\n");
- return self;
- }
-
- - windowWillResize:sender toSize:(NXSize *)aSize
- {
- /* This is not received since the controller handles it */
- printf("windowWillResize for StereoView\n");
- return self;
- }
-
- - openData:sender
- {
- const char *const ext[5] = {"dat", "data", "3d", "S3d", NULL};
-
- if (textNeedsSaving)
- [self saveInRequest:sender];
- if([openReq runModalForTypes:ext] && (fileNAME = (char *)[openReq filename])) {
- [self readSData:fileNAME];
- }
- else
- [self showError:"No file chosen or could not open file"];
- return self;
- }
-
- // saveRequest: saves the current window under its default name (found in
- // the title bar). Note that if the title bar is empty or the default title
- // is "Untitled" then saveRequest: will put up a save panel, giving the user
- // a chance to specify a real title.
-
- - saveRequest:sender
- {
- const char *fileName;
- const char *const types[2] = {"S3d",
- NULL};
-
- id curWin = [self window];
- if (textNeedsSaving)
- [self saveInRequest:sender];
- [saveReq setRequiredFileType:types[0]];
-
- if (curWin == nil)
- [self showError:"errorOnSaveRequest"];
- else {
- // Check to see if the current window is titled and the title is not
- // "Untitled". If so, save the file, else put up a save panel...
- fileName = [curWin title];
- if (strcmp (fileName, "Untitled"))
- [self saveText:curWin inPath:fileName];
- else [self saveInRequest:sender];
- }
- textNeedsSaving = 0;
- return self;
- }
-
- // saveInRequest: gives the user a chance to save the current window
- // under a new name.
-
- - saveInRequest:sender
- {
- const char *fileName;
- const char *const types[2] = {"S3d",
- NULL};
- id curWin;
-
- curWin = [self window];
- [saveReq setRequiredFileType:types[0]];
-
- if (curWin == nil)
- [self showError:"errorOnSaveIn"];
- else {
- // Get a file name from the user; use title of the window as default.
- if (([saveReq runModalForDirectory:"."
- file:[curWin title]]) &&
- (fileName = [saveReq filename]))
- [self saveText:curWin inPath:fileName];
- }
- textNeedsSaving = 0;
- return self;
- }
-
- // saveWindow writes a window out the archive file whose name is specified
- // by the second argument. The title of the current window is also set
- // accordingly.
-
- - saveText:(id)win inPath:(const char *)name
- {
- FILE *output;
- char thisline[MAXLINE];
- NXStream *stream;
- BOOL s_gets();
-
- if((output = fopen(name, "w")) == NULL) {
- sprintf(thisline, "Unable to open file %s", name);
- [self showError:thisline];
- return NULL;
- }
-
- if (delegate && [delegate respondsTo:@selector(stereoView:providePoints:)])
- [delegate stereoView:self providePoints:&stream];
-
- s_gets(thisline, MAXLINE, stream);
- while (!NXAtEOS(stream)) {
- fprintf(output,"%s",thisline);
- s_gets(thisline, MAXLINE, stream);
- }
- fclose(output);
- [win setTitle:name];
- return self;
- }
-
- // closeRequest closes the current window by simulating a click on the
- // closebutton. A check should probably be added to give the user the
- // option of saving the window before closing
-
- - closeRequest:sender
- {
- if (textNeedsSaving)
- [self saveInRequest:sender];
- /*
- [[self window] performClose:sender];
- */
- if (delegate && [delegate respondsTo:@selector(stereoView:clearText:)])
- [delegate stereoView:self clearText:fileNAME];
- strcpy(fileNAME,"Untitled");
- [self clear:self];
- [self S_Reset:self];
- textNeedsSaving = 0;
- return self;
- }
-
- - readSData:(char *)fileName
- {
-
- if ([self readFile:fileName] != NULL) {
- [self clear:self];
- [[self window] setTitle:fileName];
- [self textChanged:self];
- [self plot:self];
- }
- return self;
- }
-
- - drawSelf:(const NXRect *)rects :(int)rectCount
- {
-
- NXDrawWhiteBezel(rects,rects);
- [leftView drawSelf:&left_Rect:1];
- [rightView drawSelf:&right_Rect:1];
- return self;
- }
-
- - readFile:(char *)fileName
- {
- FILE *input;
- char thisline[MAXLINE], *cpt, *trimmer;
-
- if((input = fopen(fileName, "r")) == NULL) {
- sprintf(thisline, "Unable to open file %s", fileName);
- [self showError:thisline];
- return NULL;
- }
-
- if (delegate && [delegate respondsTo:@selector(stereoView:clearText:)])
- [delegate stereoView:self clearText:fileName];
- fgets(thisline, MAXLINE, input);
- while (!feof(input)) {
- trimmer = cpt = &thisline[0];
- while(*trimmer++ != '\n'); trimmer--;
- while(*trimmer-- == ' '); trimmer++;
- if (*trimmer != '\n') *trimmer++ = '\n'; *trimmer = '\0';
- if (delegate && [delegate respondsTo:@selector(stereoView:pointDidChange:)])
- [delegate stereoView:self pointDidChange:cpt];
- fgets(thisline, MAXLINE, input);
- }
- fclose(input);
- return self;
- }
-
- static void float_copy (register int n, register float * to, register int
- to_inc, register float * from, register int from_inc)
- {
- if (n > 0)
- while (n--) {
- *to = *from;
- to += to_inc;
- from += from_inc;
- }
- }
-
- BOOL s_gets(thisline, max, stream)
- char thisline[];
- int max;
- NXStream *stream;
- {
- int i;
-
- i = 0;
- while (!NXAtEOS(stream)) {
- thisline[i++] = NXGetc(stream);
- if (i > max) return TRUE;
- if (thisline[i-1] == '\n') {
- thisline[i] = '\0';
- return TRUE;
- }
- }
- return(FALSE);
- }
-
- - (BOOL) readData:(NXStream *)stream
- {
- float *scratch, *fpt;
- char thisline[MAXLINE] ,buffer[MAXLINE], *cpt, c;
- long int count, ncols, nchars, nlines ,tlines, expected_cols;
- datapoints **all_data = toshow, *thesedata;
- float radius;
- float shade;
-
- long pts_read = 0;
- long num_allocs = 0;
- tlines = 0;
-
- scratch = (float *) calloc(MAXNUM, sizeof(float));
- /* release existing data */
- while ((thesedata = *all_data) != (datapoints *) NULL) {
- free(thesedata->displayed);
- count = 0;
- while(thesedata->all[count] != (float *) NULL) {
- free(thesedata->all[count]);
- count++;
- }
- free(thesedata->all);
- free(thesedata);
- *all_data++ = (datapoints *) NULL;
- }
- all_data = toshow; /* read new data */
- s_gets(thisline, MAXLINE, stream);
- tlines++;
- while (!NXAtEOS(stream)) {
- radius = 0.;
- shade = NX_BLACK;
- if(sscanf(thisline, " %1s ", &c) != 1) {
- sprintf(thisline, "Unable to read a specification from text");
- [self showError:thisline];
- return NO;
- }
- switch(c) {
- case 'P': case 'p':
- /*
- * Scan here for optional arguments such as shade and radius or width
- * set shade, radius (== width for lines) pattern? labels?
- */
- sscanf(thisline, "%s %f %f", buffer, &radius, &shade);
-
- case 'N': case 'n': case 'L': case 'l': case 'B':
- case 'b':
- s_gets(thisline, MAXLINE, stream); /* load a new line */
- tlines++;
- break;
- default:
- /*
- sprintf(thisline, "the beginning of text in line %d doesn't look like a specification",tlines);
- [self showError:thisline];
- return NO;
- */
- c = 'p';
- /* s_gets(thisline, MAXLINE, stream); *//* load a new line */
- tlines++;
- }
- cpt = thisline; fpt = scratch; ncols = 0;
- while(sscanf(cpt, "%f%n", fpt, &nchars) == 1) {
- cpt += nchars;
- if(++ncols > 3) {
- sprintf(buffer,
- "More than 3 columns read in line %d\n%s\n",
- tlines-1, thisline);
- [self showError:buffer];
- return NO;
- }
- if (pts_read++ == MAXNUM) {
- sprintf(thisline, "Storage space for pts. exceeded");
- [self showError:thisline];
- return NO;
- }
- fpt++;
- }
- if (ncols == 0) {
- sprintf(buffer,
- "Line %d: <%s> does not contain numeric data",tlines,thisline);
- [self showError:buffer];
- return NO;
- }
- /* digest the rest of the lines */
- expected_cols = ncols; nlines = 1;
- while(s_gets(thisline, MAXLINE, stream)) {
- cpt = thisline; ncols = 0; tlines++;
- while(sscanf(cpt, "%f %n", fpt, &nchars) == 1) {
- cpt += nchars;
- ncols++;
- if (pts_read++ == MAXNUM) {
- sprintf(thisline, "Storage space for pts. exceeded");
- [self showError:thisline];
- return NO;
- }
- fpt++;
-
- }
- if (!ncols) break;
- nlines++;
- if (ncols != expected_cols) {
- sprintf(buffer,
- "Expected %d values but got %d values at line %d\nBad Data is:%s",
- expected_cols, ncols, tlines,thisline);
- [self showError:buffer];
- return NO;
- }
- } /* create the datapoints structure and */
- /* store the values */
- thesedata = *all_data++ = (datapoints *) malloc(sizeof(datapoints));
- if (++num_allocs > MAXALLOC) {
- sprintf(thisline, "Number Distinct Groups > MAXALLOC");
- [self showError:thisline];
- return NO;
- }
- switch(c) {
- case 'N': case 'n':
- thesedata->type = NEITHER;
- break;
- case 'L': case 'l':
- thesedata->type = LINES;
- break;
- case 'P': case 'p':
- thesedata->type = POINTS;
- thesedata->radius = radius;
- thesedata->shade = shade;
- /*
- * Store radius, shade, label here in thesedata->radius, etc.
- */
- break;
- case 'B': case 'b':
- thesedata->type = BOTH;
- break;
- }
- thesedata->all = (float **)calloc((size_t) expected_cols + 1,
- (size_t) sizeof(float *));
- for(ncols = 0; ncols < expected_cols; ncols++) {
- thesedata->all[ncols] = (float *)calloc((size_t) nlines, sizeof(float));
- float_copy(nlines, thesedata->all[ncols], 1, scratch + ncols,
- expected_cols);
- }
- thesedata->all[expected_cols] = (float *)NULL;
- /* make sure path is large enough */
- if (2*nlines >= max_path)
- realloc(path, (2*nlines)*sizeof(float));
- thesedata->npts = nlines;
- memmove(thesedata->displayed = (float **) calloc(3, sizeof(float *)),
- thesedata->all, 3 * sizeof(float *));
- }
- free(scratch);
- [self display];
- return YES;
- }
-
- @end
-